<script setup lang="ts">
import type {
  FormDesignerComponents,
  FormItemPerm
} from "../FormComponentMixin";
import { VueDraggable } from "vue-draggable-plus";
import FormComponent from "./FormComponent.vue";
import { computed, onBeforeMount, ref, watch } from "vue";
import { isDisplay } from "../FormItem";

const props = defineProps({
  mode: {
    type: String,
    default: "normal" //组件模式，free设计模式，normal 编辑模式, read 阅读模式，disable 禁用模式
  },
  rules: {
    type: Object,
    default: {}
  }
});

const _value = defineModel();
const _active = defineModel<FormDesignerComponents>("active");
const config = defineModel<FormDesignerComponents>("config");
const perm = inject<Array<FormItemPerm>>("perm");

const freeMode = computed(() => props.mode === "free");

onMounted(() => {
  if (!_value.value) {
    _value.value = {};
  }
});

function reloadSpan() {
  //初始化分栏数据值
  const spanProps = config.value.props;
  if (spanProps.number > spanProps.columns.length) {
    for (let i = 0; i < spanProps.number; i++) {
      if (!spanProps.columns[i]) {
        config.value.props.columns.push([]);
      }
    }
  } else {
    spanProps.columns.length = spanProps.number;
  }
}

const handleItemValueChange = (item: FormDesignerComponents, val: any) => {
  if (
    _value.value &&
    Object.prototype.hasOwnProperty.call(_value.value, item.code)
  ) {
    _value.value[item.code] = val;
  }
};

onBeforeMount(reloadSpan);
watch(() => config.value.props.number, reloadSpan);
</script>

<template>
  <el-row :gutter="config.props.gutter">
    <el-col
      v-for="(cols, i) in config.props.columns"
      :key="`col_${i}`"
      :span="config.props.span / config.props.number"
    >
      <vue-draggable
        v-model="config.props.columns[i]"
        :animation="150"
        group="FormDesign"
        :disabled="!freeMode"
        :ghostClass="freeMode ? 'w-f-cp-select' : ''"
        :class="{ 'span-layout-container': freeMode }"
      >
        <template v-for="(item, idx) in cols" :key="item.id">
          <div v-if="isDisplay(perm, item.code)">
            <el-form-item
              v-if="item.props.isFormItem"
              :label="item.name"
              :required="item.props.required"
              :prop="item.code"
              @click.stop="_active = item"
              :class="{
                'w-form-d-item': freeMode,
                'w-form-cp-active': _active?.id === item.id && freeMode,
                'w-form-cp-nlb': item.props.hideLabel
              }"
            >
              <FormComponent
                :index="idx"
                :parents="cols"
                :config="item"
                :mode="mode"
                v-model="_value[item.code]"
                v-model:active="_active"
                :type="item.type"
                @change="handleItemValueChange"
              />
            </el-form-item>
            <FormComponent
              v-else-if="item.props.isSubform"
              :config="item"
              v-model="_value[item.code]"
              v-model:active="_active"
              :mode="mode"
              :type="item.type"
              :rules="props.rules"
              @click.stop="_active = item"
              :index="idx"
              :parents="cols"
              :class="{
                'w-form-d-item': freeMode,
                'w-form-cp-active': _active?.id === item.id && freeMode
              }"
            />
            <FormComponent
              v-else
              :config="item"
              v-model="_value"
              v-model:active="_active"
              :mode="mode"
              :type="item.type"
              :rules="props.rules"
              @click.stop="_active = item"
              :index="idx"
              :parents="cols"
              :class="{
                'w-form-d-item': freeMode,
                'w-form-cp-active': _active?.id === item.id && freeMode
              }"
            />
          </div>
        </template>
      </vue-draggable>
    </el-col>
  </el-row>
</template>

<style lang="scss" scoped>
@use "/src/assets/style/form/global";
:deep(.span-layout-container) {
  width: 100%;
  min-height: 50px;
  background-color: $main-bgc;
}

.w-f-cp-select {
  border: 1px dashed var(--el-color-primary) !important;
  border-radius: 2px;
}
</style>
